package cn.kgc.controller;

import cn.kgc.base.vo.OrderItemVo;
import cn.kgc.base.vo.OrderVo;
import cn.kgc.base.vo.UmsMemberReceiveAddressVo;
import cn.kgc.client.CartFeignClient;
import cn.kgc.client.UmsFeignClient;
import cn.kgc.commons.exception.HttpException;
import cn.kgc.commons.util.RedisUtil;
import cn.kgc.commons.util.UserContextHolder;
import cn.kgc.commons.vo.Result;
import cn.kgc.constant.OrderConstant;
import cn.kgc.entity.OmsOrder;
import cn.kgc.service.OmsOrderService;
import cn.kgc.service.OrderService;
import cn.kgc.vo.OrderConfirmVo;
import cn.kgc.vo.OrderSubmitVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * <p>添加描述信息</p>
 *
 * @author 卢传琪
 */
@RequestMapping("/order")
@RestController
@Api(tags = "订单管理")
@Slf4j
public class OmsOrderController {
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private UmsFeignClient umsFeignClient;
    @Resource
    private CartFeignClient cartFeignClient;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private OrderService orderService;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private OmsOrderService omsOrderService;

    @GetMapping("/getOrderVo")
    @ApiOperation(value = "根据订单的编号获得订单的信息",httpMethod = "GET",produces = "application/json;charset=UTF-8",response = Result.class)
    @CrossOrigin
    @ApiImplicitParam(name = "orderSn",value = "订单编号",required = true,dataType = "String",paramType = "query")
    public OrderVo getOrderInfoByOrderSn(@RequestParam(name = "orderSn") String orderSn) {
        LambdaQueryWrapper<OmsOrder> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(OmsOrder::getOrderSn,orderSn);
        OmsOrder omsOrder = omsOrderService.getOne(lambdaQueryWrapper);
        OrderVo orderVo=new OrderVo();
        BeanUtils.copyProperties(omsOrder,orderVo);
        return orderVo;
    }

    //1 获得订单相关信息（收货地址（用户服务获得）  购物车中选中的商品（购物车服务中获得） 应付金额 总金额）
    @GetMapping("/getOrderConfirm")
    @ApiOperation(value = "获得订单相关信息",httpMethod = "GET",produces = "application/json;charset=UTF-8",response = Result.class)
    @CrossOrigin
    public OrderConfirmVo getOrderConfirm(){
        // 获得登录用户id
        long userId= Long.parseLong(UserContextHolder.getInstance().getUserId());
        OrderConfirmVo orderConfirmVo=new OrderConfirmVo();
        //获得登录用户的收货地址（远程接口）
        CompletableFuture<Void> future1=CompletableFuture.runAsync(()->{
            Result<List<UmsMemberReceiveAddressVo>> result=umsFeignClient.getUmsMemberReceiveAddress(userId);
            if (result.getData()!=null){//如果服务没有降级，保存所有的收货地址
                orderConfirmVo.setAddressVoList(result.getData());
            }
        },threadPoolExecutor);

        //获得登录用户的购物车中选中的商品信息（远程接口）
        CompletableFuture<Void> future2=CompletableFuture.runAsync(()->{
            Result<List<OrderItemVo>> result=cartFeignClient.getOrderItemVo(userId);
            if (result.getData()!=null){
                orderConfirmVo.setCartItemVoList(result.getData());
                //总价
                BigDecimal totalPrice=new BigDecimal(0);
                List<OrderItemVo> orderItemVoList=orderConfirmVo.getCartItemVoList();
                for (OrderItemVo orderItemVo : orderItemVoList) {
                    totalPrice=totalPrice.add(orderItemVo.getTotalPrice());
                }
                orderConfirmVo.setPayTotalPrice(totalPrice);
                orderConfirmVo.setTotalPrice(totalPrice);
            }
        },threadPoolExecutor);

        try {
            //异步任务都执行完成以后，程序再向下执行
            CompletableFuture.allOf(future1,future2).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //生成令牌
        String token= UUID.randomUUID().toString().replaceAll("-","");
        //将令牌保存到redis中
        String orderTokenKey= OrderConstant.ORDER_TOKEN_PREFIX+token;
        redisUtil.set(orderTokenKey,token,OrderConstant.ORDER_TOKEN_TIME, TimeUnit.MINUTES);
        //返回令牌
        orderConfirmVo.setOrderToken(token);
        return orderConfirmVo;
    }
    //2 生成订单（保存：订单信息，订单商品信息，锁定库存）
    @PostMapping("/generateOrder")
    @ApiOperation(value = "生成订单，返回订单编号", produces = "application/json;charset=utf-8",
            httpMethod = "POST", response = Result.class)
    @CrossOrigin
    public Result<String> generateOrder(@RequestBody OrderSubmitVO orderSubmitVO){
        //保证接口幂等性
        String orderToken= orderSubmitVO.getOrderToken();
        String orderTokenKey=OrderConstant.ORDER_TOKEN_PREFIX+orderToken;
        //判断接口幂等性
        boolean flag=redisUtil.execute(orderTokenKey,orderToken);
        if (!flag){
            throw new HttpException(50001, HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
        long memberId=Long.parseLong(UserContextHolder.getInstance().getUserId());
        String memberName=UserContextHolder.getInstance().getUserName();
        String orderSn=orderService.generateOrderInfo(orderSubmitVO,memberId,memberName);

        if (orderSn!=null){
            OmsOrder omsOrder=new OmsOrder();
            omsOrder.setOrderSn(orderSn);
            rabbitTemplate.convertAndSend(OrderConstant.ORDER_EXCHANGE,OrderConstant.CREATE_ORDER_ROUTING_KEY,omsOrder);
        }

        return Result.success(orderSn,"http://mall-oms/order/generateOrder");
    }
}
